import * as R from 'ramda'
import * as vscode from 'vscode'
import { CompletionItem, Position, TextDocument } from 'vscode'
import { 常用汉字 } from './data/常用汉字'
import { 获得当前输入字段, 获得文档补全项, 获得系统补全项 } from './lib/VSC扩展'
import { 包含中文 } from './lib/字符串扩展'
import { 获得中文字符表示 } from './lib/获得中文表示'
import { 获得配置 } from './lib/获得配置'
import { 获得输入法补全项 } from './lib/输入法'

var log = (...args: unknown[]) => console.log('中文代码快速补全:', ...args)
var 用户配置 = 获得配置()

async function 完成项提供者(document: TextDocument, position: Position) {
  // 如果是md文件, 并且用户没有打开md补全, 则什么都不做.
  if (document.languageId == 'markdown' && 用户配置.markdown补全 != 'yes') return []

  // 必要变量
  var 补全项: CompletionItem[] = []
  var 输入字段 = await 获得当前输入字段()

  // 如果输入的是中文, 那么不需要构造翻译.
  if (包含中文(输入字段)) {
    return []
  }

  // 获得系统补全项
  if (用户配置.分析vsc提供的补全项 == 'yes') {
    var 补全项提供器 = await 获得系统补全项(document.uri, position)
    // 调用'获得系统补全项'时会调用'完成项提供者'函数, 这会导致无限循环.
    // '获得系统补全项'函数内部做了处理, 如果是无限循环的场景, 就直接返回null.
    // 这种情况下, 这里就直接返回空补全项.
    if (补全项提供器 == null) return []
    补全项 = 补全项.concat(补全项提供器.items)
  }

  // 获得文档补全项
  if (用户配置.分析当前文档的词作为补全项 == 'yes') {
    var 文档字段补全项 = 获得文档补全项(document)
    补全项 = 补全项.concat(文档字段补全项)
  }

  // 获得输入法补全项
  if (用户配置.使用输入法 != 'no') {
    var 输入法补全项 = await 获得输入法补全项(用户配置.使用输入法, 输入字段, 用户配置.代理地址).catch((e) => {
      console.error(e)
      vscode.window.showInformationMessage(`调用 ${用户配置.使用输入法} 输入法接口出错：` + e)
      return []
    })
    补全项 = 补全项.concat(输入法补全项)
  }

  // 做以下处理:
  // - 去重.
  // - 不包含中文的关键词没必要加拼音,因此过滤.
  // - 现在正在输入的字段不需要加入补全项.
  // - 无论这个函数是否返回结果,vsc总会检测和自动补全定义的片段(Snippet),所以这里把片段过滤掉.
  补全项 = R.uniqWith((a, b) => a.label == b.label, 补全项)
    .filter((a) => 包含中文(a.label.toString()))
    .filter((a) => a.label != 输入字段)
    .filter((a) => a.kind != vscode.CompletionItemKind.Snippet)

  // 设置补全项的实际补全内容
  补全项 = 补全项.map((a) => R.set(R.lensProp('insertText'), a.label.toString(), a))

  // 设置补全项的 filterText
  补全项 = 补全项.map((a) =>
    R.set(R.lensProp('filterText'), `${获得中文字符表示(用户配置.提示方式, a.label.toString())}`, a),
  )

  return new vscode.CompletionList(补全项, true)
}

export function activate(context: vscode.ExtensionContext) {
  log('插件已启动')
  context.subscriptions.push(
    vscode.languages.registerCompletionItemProvider(
      { scheme: 'file', language: '*' },
      { provideCompletionItems: 完成项提供者, resolveCompletionItem: () => null },
      ...['$', '.', ':', ...常用汉字],
    ),
  )
}

export function deactivate() {}
